<template>
	<view class="waterfalls-box" :style="{ height: height + 'px', overflow: overflow }">
		<!--  #ifdef  MP-WEIXIN -->
		<view
			v-for="(item, index) of lists"
			class="waterfalls-list"
			:key="item[idKey]"
			:id="'waterfalls-list-id-' + item[idKey]"
			:ref="'waterfalls-list-id-' + item[idKey]"
			:style="{
				'--offset': offset + 'px',
				'--cols': cols,
				top: allPositionArr[index].top || 0,
				left: allPositionArr[index].left || 0
			}"
			@click="$emit('wapper-lick', item)"
		>
			<image
				class="waterfalls-list-image"
				mode="widthFix"
				:class="{ single }"
				:style="imageStyle"
				:src="item[imageSrcKey] || ' '"
				@load="imageLoadHandle(index)"
				@error="imageLoadHandle(index)"
				@click="imageClick(item, index)"
			/>
			<slot name="slot{{index}}" />
			
			<!-- 被选中状态 -->
			<view class="mark" v-if="item.checked" @click="imageClick(item, index)">
				<view class="check-btn">
					<view class="check-icon">
						<uni-icons type="checkmarkempty" size="32rpx" color="#fff"></uni-icons>
					</view>
				</view>
			</view>
		</view>
		<!--  #endif -->

		<!--  #ifndef  MP-WEIXIN -->
		<view
			v-for="(item, index) of list"
			class="waterfalls-list"
			:key="item[idKey]"
			:id="'waterfalls-list-id-' + item[idKey]"
			:ref="'waterfalls-list-id-' + item[idKey]"
			:style="{
				'--offset': offset + 'px',
				'--cols': cols,
				...listStyle,
				...(allPositionArr[index] || {})
			}"
			@click="$emit('wapper-lick', item)"
		>
			<image
				class="waterfalls-list-image"
				:class="{ single }"
				mode="widthFix"
				:style="imageStyle"
				:src="item[imageSrcKey] || ' '"
				@load="imageLoadHandle(index)"
				@error="imageLoadHandle(index)"
				@click="$emit('image-click', item)"
			/>
			<slot v-bind="item" />
			
			<!-- 被选中状态 -->
			<view class="mark" v-if="item.checked" @click="imageClick(item, index)">
				<view class="check-btn">
					<view class="check-icon">
						<uni-icons type="checkmarkempty" size="32rpx" color="#fff"></uni-icons>
					</view>
				</view>
			</view>
		</view>
		<!--  #endif -->
	</view>
</template>
<script>
export default {
	props: {
		list: { type: Array, required: true },
		// offset 间距，单位为 px
		offset: { type: Number, default: 10 },
		// 列表渲染的 key 的键名，值必须唯一，默认为 id
		idKey: { type: String, default: 'id' },
		// 图片 src 的键名
		imageSrcKey: { type: String, default: 'image_url' },
		// 列数
		cols: { type: Number, default: 2, validator: num => num >= 2 },
		imageStyle: { type: Object },

		// 是否是单独的渲染图片的样子，只控制图片圆角而已
		single: { type: Boolean, default: false },

		// #ifndef MP-WEIXIN
		listStyle: { type: Object },
		// #endif
		
		// 是否多选
		showSelect: { type: Boolean, default: false },
		// 是否已全选
		allSelect: { type: Boolean, default: false },
	},
	data() {
		return {
			lists: [],
			topArr: [], // left, right 多个时依次表示第几列的数据
			allPositionArr: [], // 保存所有的位置信息
			allHeightArr: [], // 保存所有的 height 信息
			height: 0, // 外层包裹高度
			oldNum: 0,
			num: 0,
			overflow: 'hidden'
		};
	},
	created() {
		this.refresh();
	},
	watch: {
		list: {
			handler(newVal, oldVal) {
				this.lists = this.list.map((item, index) => {
					item.index = index;
					return item;
				});
			}
		},
		allSelect: {
			handler(newVal) {
				console.log(newVal);
				this.lists.forEach(item => {
					if (newVal) {
						item.checked = true;
					} else {
						item.checked = false;
					}
				})
				let selectList = this.lists.filter(v => v.checked);
				this.$emit('image-click', {item: null, selectList});
			}
		}
	},
	methods: {
		imageLoadHandle(index) {
			setTimeout(() => {
				const id = 'waterfalls-list-id-' + this.lists[index][this.idKey],
					query = uni.createSelectorQuery().in(this);
				query
					.select('#' + id)
					.fields({ size: true }, data => {
						this.num++;
						// console.log('data.height ==>', data.height);
						this.$set(this.allHeightArr, index, data.height);
						// console.log('allHeightArr ==>', this.allHeightArr);
						if (this.num === this.lists.length) {
							for (let i = this.oldNum; i < this.num; i++) {
								const getTopArrMsg = () => {
									// console.log('topArr ==>', this.topArr);
									let arrtmp = [...this.topArr].sort((a, b) => a - b);
									// console.log('arrtmp ==>', arrtmp);
									return {
										shorterIndex: this.topArr.indexOf(arrtmp[0]),
										shorterValue: arrtmp[0],
										longerIndex: this.topArr.indexOf(arrtmp[this.cols - 1]),
										longerValue: arrtmp[this.cols - 1]
									};
								};
				
								const { shorterIndex, shorterValue } = getTopArrMsg();
								const position = {
									top: shorterValue + 'px',
									left: (data.width + this.offset) * shorterIndex + 'px'
								};
								this.$set(this.allPositionArr, i, position);
								this.topArr[shorterIndex] = shorterValue + this.allHeightArr[i] + this.offset;
								// console.log('topArrShort ==>', this.topArr[shorterIndex]);
								this.height = getTopArrMsg().longerValue - this.offset;
							}
							this.oldNum = this.num;
							this.overflow = 'visible';
							// 完成渲染 emit `image-load` 事件
							this.$emit('image-load', {num: this.oldNum, height: this.height, pos: this.allPositionArr});
						}
					})
					.exec();
			}, 500)
		},
		refresh() {
			let arr = [];
			for (let i = 0; i < this.cols; i++) {
				arr.push(0);
			}
			this.topArr = arr;
			this.num = 0;
			this.oldNum = 0;
			this.height = 0;
		},
		imageClick(item, index) {
			if (this.showSelect) {
				this.lists[index].checked = !this.lists[index].checked;
			}
			let selectList = this.lists.filter(v => v.checked);
			this.$emit('image-click', {item, selectList});
		}
	}
};
</script>
<style lang="scss" scoped>
// 这里可以自行配置
$border-radius: 20rpx;
$check-color: #111;

.waterfalls-box {
	position: relative;
	width: 100%;
	// overflow: hidden;
	.waterfalls-list {
		width: calc((100% - var(--offset) * (var(--cols) - 1)) / var(--cols));
		position: absolute;
		background-color: #fff;
		border-radius: $border-radius;
		background-color: #efefef;
		// 防止刚开始渲染时堆叠在第一幅图的地方
		left: calc(-50% - var(--offset));
		// &:first-child {
		// 	max-height: 600rpx !important;
		// 	overflow: hidden;
		// }
		.waterfalls-list-image {
			position: relative;
			width: 100%;
			will-change: transform;
			border-radius: $border-radius $border-radius 0 0;
			display: block;
			&.single {
				border-radius: $border-radius;
			}
		}
		.waterfalls-list-image::after {
			content: '';
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			z-index: 20;
			background-color: rgba(0, 0, 0, 0.04);
			border-radius: $border-radius;
		}
	}

	/* 扩展多选样式 */
	.mark {
		position: absolute;
		top: 0;
		bottom: 0;
		left: 0;
		right: 0;
		z-index: 20;
		background-color: rgba($color: #000000, $alpha: 0.3);
		border-radius: $border-radius;
	}
	.check-btn {
		position: absolute;
		right: 20rpx;
		bottom: 20rpx;
	}
	.check-icon {
		display: flex;
		justify-content: center;
		align-items: center;
		width: 48rpx;
		height: 48rpx;
		background-color: $check-color;
		border: 2rpx solid $check-color;
		border-radius: 16rpx;
	}
}
</style>
